﻿using CoachingOrganizer.Logic.Helpers;
using CoachingOrganizer.Logic.Logic.Tools.EmotionsPack;
using CoachingOrganizer.Toolkit.Events;
using CoachingOrganizer.Toolkit.Threading.CollectionsDecorators;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoachingOrganizer.Logic.Models.Tools.EmotionsPack
{
    public class EmotionTraceModel
    {
        private readonly string _emotionName;
        private readonly SimpleCollectionLoadDecorator<EmotionTraceItemModel> _traceItems;

        public string EmotionName
        {
            get { return _emotionName; }
        }

        public IEnumerable<EmotionTraceItemModel> TraceItems
        {
            get { return _traceItems.Items; }
        }

        public event EventHandler TraceItemsChanged
        {
            add { _traceItems.ItemsChanged += value; }
            remove { _traceItems.ItemsChanged -= value; }
        }

        public event NotifyCollectionChangedEventHandler TraceItemsCollectionChanged
        {
            add { _traceItems.ItemsCollectionChanged += value; }
            remove { _traceItems.ItemsCollectionChanged -= value; }
        }

        internal Func<string, byte[], ActionResult<EmotionTraceItemLogic>> AddNewTraceItemDelegate;

        internal Func<ActionResult<IEnumerable<EmotionTraceItemLogic>>> EnumerateTraceItemsDelegate;

        public EmotionTraceModel(string emotionName)
        {
            _emotionName = emotionName;
            _traceItems = new SimpleCollectionLoadDecorator<EmotionTraceItemModel>(EnumerateTraceItems);
        }

        public async Task LoadTraceItemsAsync(System.Threading.CancellationToken cancelLoad)
        {
            await Task.Run(() => _traceItems.FillItemsList(), cancelLoad);
        }

        public async Task LoadTraceItemsAsync()
        {
            await Task.Run(() => _traceItems.FillItemsList());
        }

        public async Task<ActionResult> AddNewTraceItem(string traceItemName, byte[] picture)
        {
            return await Task.Run(() =>
            {
                Func<string, byte[], ActionResult<EmotionTraceItemLogic>> addNewTraceItemDelegate = AddNewTraceItemDelegate;
                if (addNewTraceItemDelegate == null)
                    ActionResult.GetErrorResult(new NotSupportedException());
                ActionResult<EmotionTraceItemLogic> newTraceItemResult = addNewTraceItemDelegate(traceItemName, picture);
                if (newTraceItemResult.IsValid)
                    _traceItems.ModifyCollection(col => col.Add(newTraceItemResult.Result.Model));
                return newTraceItemResult.IsValid ? ActionResult.ValidResult : ActionResult.GetErrorResult(newTraceItemResult);
            });
        }

        public void ModifyTraceItemsCollection(Action<IList<EmotionTraceItemModel>> modificationDelegate)
        {
            _traceItems.ModifyCollection(modificationDelegate);
        }

        private ActionResult<IEnumerable<EmotionTraceItemModel>> EnumerateTraceItems()
        {
            return UpdateHelper.EnumerateModels(EnumerateTraceItemsDelegate, l => l.Model);
        }
    }
}
